#define _WIN32_WINNT        0x0400  // kharmon.  08-01-06.  Needed for ReadDirectoryChangesW

#include <windows.h>

#include "lib.h"
#include "patch.h"
#include "detreq.h"
#include "client.h"
#include "patchsrv.h"

DetermineRequest::DetermineRequest(Client* client)
	: Protocol(client)
{
}

#ifdef _DEBUG

static const char* GetProtocolName(int protocol)
{
    static const char* protocol_name[] = {
        "IDLE",
		"REQ_LIST", 
        "REQ_DOWNLOAD",
		"REQ_PKG_FILELIST", 
        "REQ_RSYNC",
	    "RECV_PKG_UPDATE", 
        "SPEEDTEST",
		"CHANGESPEED"
    };

    if ( protocol < 0 || protocol > 7 )
    {
        return "INVALID";
    }

    return protocol_name[protocol];
}

#endif



void
DetermineRequest::netIn(int32 Amt)
{
	int32 len;
	uint8* msg;
	int32 ieat;

	if (client->iused < 1)
	{
		client->readNet();
		return;
	}
	
	if (client->in[0] == 0)
	{
		client->setMsgFormat(Client::DOUBLE_BYTE);
		client->setMsgOverhead(3);
	}
	else
	{
		client->setMsgFormat(Client::SINGLE_BYTE);
		client->setMsgOverhead(1);
	}

	if (client->getMsgFormat() == Client::SINGLE_BYTE)
		ieat = client->msgGet(client->in, (uint8 *)0);
	else
		ieat = client->msgGet(client->in+1, (uint16*)0)+1;
	
	if (client->iused < ieat)
	{
		client->readNet();
		return;
	}

	msg = client->in + client->getMsgOverhead();
	len = ieat-client->getMsgOverhead();

	if (PatchServer::This->isStopping())
	{
		client->eatIBuf(ieat);
		client->errmsg(EM_ServerDownForMaintenance);
		return;
	}

	if (len > 0)
	{
		int32 i, result;

		for (i = Client::IDLE + 1; i < Client::NUMPROTOCOLS; i++)
		{
			if (client->handler[i]->recognize(msg, len))
			{
                DEBUGMSG(("Protocol %s message of %d bytes recognized: %c%c", GetProtocolName(i), len, msg[0], msg[0] == 'M'?msg[1]:0));
				result = client->handler[i]->start(msg, len);

				client->eatIBuf(ieat);

				if (result == EM_Success)
				{
					client->protocol = i;
					client->handler[i]->netIn(client->iused);
					return;
				}
				else if (result == EM_NoError)
				{
					netIn(client->iused);
					return;
				}

				client->errmsg((uint8)(result & 0xff));
				return;
			}
		}
	}

	DEBUGMSG(("Unknown Message: '%c%c'", msg[0], msg[0] == 'M'?msg[1]:0));

	client->eatIBuf(ieat);
	client->errmsg(EM_BadRequest);
}

void
DetermineRequest::netOut(int32 /*Amt*/)
{
	// was writting error msg...start new protocol
	//
	client->protocolDone();
}
